home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include <stdio.h>
- #ifndef NOUNISTD_H
- #include <unistd.h>
- #endif
- #include "dalloca.h"
- #include "head.h"
-
- #define TOL 1.0e-20
-
- #define ERRR (-1)
- #ifndef NULL
- #define NULL 0
- #endif
-
- static int svdcmp(double **a, int m, int n, double *w, double **v);
- static int svbksb(double **u, double *w, double **v, int m, int n, double *b, double *x);
-
- int Ft_svdfit(double **coef, double *y, double *sig, int ndata, double *a, int ma, double **v, double *w, double *chisq)
- {
- int j,i;
- double wmax,tmp,thresh,sum,**u,*b;
-
- ADVECTOR(b, 1, ndata, "svdfit", Ft_catcher);
- ADMATRIX(u, 1, ndata, 1, ma, "svdfit", Ft_catcher);
-
- for (i=1;i<=ndata;i++) {
- tmp=1.0/sig[i];
- for (j=1;j<=ma;j++) u[i][j]=coef[j][i]*tmp;
- b[i]=y[i]*tmp;
- }
- if (svdcmp(u,ndata,ma,w,v) == ERRR) {
- Ft_catcher(ERRR);
- }
- wmax=0.0;
- for (j=1;j<=ma;j++)
- if (w[j] > wmax) wmax=w[j];
- thresh=TOL*wmax;
- for (j=1;j<=ma;j++)
- if (w[j] < thresh) w[j]=0.0;
- if (svbksb(u,w,v,ndata,ma,b,a) == ERRR) {
- Ft_catcher(ERRR);
- }
- *chisq=0.0;
- for (i=1;i<=ndata;i++) {
- for (sum=0.0,j=1;j<=ma;j++) sum += a[j]*coef[j][i];
- *chisq += (tmp=(y[i]-sum)/sig[i],tmp*tmp);
- }
- return(1);
- }
-
- #undef TOL
-
- static double at,bt,ct;
- #define PYTHAG(a,b) ((at=fabs(a)) > (bt=fabs(b)) ? (ct=bt/at,at*sqrt(1.0+ct*ct)) : (bt ? (ct=at/bt,bt*sqrt(1.0+ct*ct)): 0.0))
-
- static double maxarg1,maxarg2;
- #define MAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ? (maxarg1) : (maxarg2))
- #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
-
- static int svdcmp(double **a, int m, int n, double *w, double **v)
- {
- int flag, i, its, j, jj, k, l, nm;
- double c, f, h, s, x, y, z;
- double anorm=0.0, g=0.0;
- double scale=0.0;
- double *rv1;
-
- if (m < n) {
- fprintf(stderr, "svdcmp: You must augment A with extra zero rows.");
- return(ERRR);
- }
- ADVECTOR(rv1, 1, n, "svdcmp", return);
-
- l = nm = 0;
- for (i=1;i<=n;i++) {
- l = i+1;
- rv1[i] = scale*g;
- g = s = scale = 0.0;
- if (i <= m) {
- for (k=i;k<=m;k++)
- scale += fabs(a[k][i]);
- if (scale) {
- for (k=i;k<=m;k++) {
- a[k][i] /= scale;
- s += a[k][i]*a[k][i];
- }
- f=a[i][i];
- g = -SIGN(sqrt(s),f);
- h = f*g-s;
- a[i][i] = f-g;
- if (i != n) {
- for (j=l;j<=n;j++) {
- for (s=0.0,k=i;k<=m;k++)
- s += a[k][i]*a[k][j];
- f = s/h;
- for (k=i;k<=m;k++)
- a[k][j] += f*a[k][i];
- }
- }
- for (k=i;k<=m;k++)
- a[k][i] *= scale;
- }
- }
- w[i] = scale*g;
- g = s = scale = 0.0;
- if (i <= m && i != n) {
- for (k=l;k<=n;k++)
- scale += fabs(a[i][k]);
- if (scale) {
- for (k=l;k<=n;k++) {
- a[i][k] /= scale;
- s += a[i][k]*a[i][k];
- }
- f = a[i][l];
- g = -SIGN(sqrt(s),f);
- h = f*g-s;
- a[i][l] = f-g;
- for (k=l;k<=n;k++)
- rv1[k]=a[i][k]/h;
- if (i != m) {
- for (j=l;j<=m;j++) {
- for (s=0.0,k=l;k<=n;k++)
- s += a[j][k]*a[i][k];
- for (k=l;k<=n;k++)
- a[j][k] += s*rv1[k];
- }
- }
- for (k=l;k<=n;k++)
- a[i][k] *= scale;
- }
- }
- anorm=MAX(anorm,(fabs(w[i])+fabs(rv1[i])));
- }
- for (i=n;i>=1;i--) {
- if (i < n) {
- if (g) {
- for (j=l;j<=n;j++)
- v[j][i] = (a[i][j]/a[i][l])/g;
- for (j=l;j<=n;j++) {
- for (s=0.0,k=l;k<=n;k++)
- s += a[i][k]*v[k][j];
- for (k=l;k<=n;k++)
- v[k][j] += s*v[k][i];
- }
- }
- for (j=l;j<=n;j++)
- v[i][j]=v[j][i]=0.0;
- }
- v[i][i] = 1.0;
- g = rv1[i];
- l = i;
- }
- for (i=n;i>=1;i--) {
- l = i+1;
- g = w[i];
- if (i < n)
- for (j=l;j<=n;j++)
- a[i][j] = 0.0;
- if (g) {
- g = 1.0/g;
- if (i != n) {
- for (j=l;j<=n;j++) {
- for (s=0.0,k=l;k<=m;k++)
- s += a[k][i]*a[k][j];
- f = (s/a[i][i])*g;
- for (k=i;k<=m;k++)
- a[k][j] += f*a[k][i];
- }
- }
- for (j=i;j<=m;j++)
- a[j][i] *= g;
- } else {
- for (j=i;j<=m;j++)
- a[j][i]=0.0;
- }
- ++a[i][i];
- }
- for (k=n;k>=1;k--) {
- for (its=1;its<=30;its++) {
- flag = 1;
- for (l=k;l>=1;l--) {
- nm = l-1;
- if (fabs(rv1[l])+anorm == anorm) {
- flag=0;
- break;
- }
- if (fabs(w[nm])+anorm == anorm) break;
- }
- if (flag) {
- c = 0.0;
- s = 1.0;
- for (i=l;i<=k;i++) {
- f=s*rv1[i];
- if (fabs(f)+anorm != anorm) {
- g = w[i];
- h = PYTHAG(f,g);
- w[i]=h;
- h=1.0/h;
- c=g*h;
- s=(-f*h);
- for (j=1;j<=m;j++) {
- y=a[j][nm];
- z=a[j][i];
- a[j][nm]=y*c+z*s;
- a[j][i]=z*c-y*s;
- }
- }
- }
- }
- z=w[k];
- if (l == k) {
- if (z < 0.0) {
- w[k] = -z;
- for (j=1;j<=n;j++)
- v[j][k]=(-v[j][k]);
- }
- break;
- }
- if (its == 30) {
- fprintf(stderr, "svdcmp: No convergence in 30 iterations.\n");
- return(ERRR);
- }
- x=w[l];
- nm=k-1;
- y=w[nm];
- g=rv1[nm];
- h=rv1[k];
- f=((y-z)*(y+z)+(g-h)*(g+h))/(2.0*h*y);
- g=PYTHAG(f,1.0);
- f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
- c=s=1.0;
- for (j=l;j<=nm;j++) {
- i=j+1;
- g=rv1[i];
- y=w[i];
- h=s*g;
- g=c*g;
- z=PYTHAG(f,h);
- rv1[j]=z;
- c=f/z;
- s=h/z;
- f=x*c+g*s;
- g=g*c-x*s;
- h=y*s;
- y=y*c;
- for (jj=1;jj<=n;jj++) {
- x=v[jj][j];
- z=v[jj][i];
- v[jj][j]=x*c+z*s;
- v[jj][i]=z*c-x*s;
- }
- z=PYTHAG(f,h);
- w[j]=z;
- if (z) {
- z=1.0/z;
- c=f*z;
- s=h*z;
- }
- f=(c*g)+(s*y);
- x=(c*y)-(s*g);
- for (jj=1;jj<=m;jj++) {
- y=a[jj][j];
- z=a[jj][i];
- a[jj][j]=y*c+z*s;
- a[jj][i]=z*c-y*s;
- }
- }
- rv1[l]=0.0;
- rv1[k]=f;
- w[k]=x;
- }
- }
- return(1);
- }
-
- #undef SIGN
- #undef MAX
- #undef PYTHAG
-
- static int svbksb(double **u, double *w, double **v, int m, int n, double *b, double *x)
- {
- int jj, j, i;
- double s, *tmp;
-
- ADVECTOR(tmp, 1, n, "svbksb", return);
-
- for (j=1;j<=n;j++) {
- s=0.0;
- if (w[j]) {
- for (i=1;i<=m;i++) s += u[i][j]*b[i];
- s /= w[j];
- }
- tmp[j]=s;
- }
- for (j=1;j<=n;j++) {
- s=0.0;
- for (jj=1;jj<=n;jj++) s += v[j][jj]*tmp[jj];
- x[j]=s;
- }
- return(1);
- }
-
- int Ft_svdvar(double **v, int ma, double *w, double **cvm)
- {
- int k,j,i;
- double sum, *wti;
-
- ADVECTOR(wti, 1, ma, "svdvar", Ft_catcher);
-
- for (i=1;i<=ma;i++) {
- wti[i]=0.0;
- if (w[i]) wti[i]=1.0/(w[i]*w[i]);
- }
- for (i=1;i<=ma;i++) {
- for (j=1;j<=i;j++) {
- for (sum=0.0,k=1;k<=ma;k++) sum += v[i][k]*v[j][k]*wti[k];
- cvm[j][i]=cvm[i][j]=sum;
- }
- }
- return(0);
- }
-